```src/renderer/views/train/index.vue
<template>
  <div class="common-layout">
    <div style="font-size: 26px; margin-bottom: 10px">
      <el-breadcrumb :separator-icon="ArrowRight">
        <el-breadcrumb-item :to="{ path: '/' }"
          ><span style="color: #c2c6cc">首页</span></el-breadcrumb-item
        >
        <el-breadcrumb-item :to="{ path: '/thematic-education' }">
          <span style="color: #c2c6cc">专题教育</span></el-breadcrumb-item
        >
        <el-breadcrumb-item>
          <a href="/" style="color: #c2c6cc">专题学习</a></el-breadcrumb-item
        >
      </el-breadcrumb>
    </div>
    <div class="layout-container">
      <div class="left">
        <el-descriptions title="课程信息" :column="1" :size="size" border>
          <template #title>
            <h2><span style="color: white">课程信息</span></h2>
          </template>
          <el-descriptions-item>
            <template #label>
              <div class="cell-item">课程名称</div>
            </template>
            {{ planInfo.planName }}
          </el-descriptions-item>
          <el-descriptions-item>
            <template #label>
              <div class="cell-item">课件</div>
            </template>
            {{ planInfo.planCourses && planInfo.planCourses.length }}
          </el-descriptions-item>
          <el-descriptions-item>
            <template #label>
              <div class="cell-item">时长</div>
            </template>
            {{ planInfo.totalSecond }}
          </el-descriptions-item>
        </el-descriptions>
        <div class="user-title">
          <div>
            <h2>参与培训人员</h2>
          </div>
          <div>
            <el-button type="primary" @click="sign">{{
              signButtonText
            }}</el-button>
          </div>
        </div>
        <div class="participants">
          <div
            class="participant"
            v-for="(item, index) in userList"
            :key="index"
            :style="{ backgroundColor: item.leave ? '#3a3a4b ' : 'green' }"
          >
            {{ item.userName }}
          </div>
        </div>
      </div>
      <div class="center" v-if="trainState">
        <div class="video-area">
          <video
            :src="courseUrl"
            autoplay
            controls
            @ended="handleVideoEnded"
          ></video>
        </div>
        <div class="video-section" ref="scrollContainer">
          <div v-for="(item, index) in planInfo.planCourses" :key="index">
            <div
              class="video-section-item"
              :style="{
                backgroundColor: playIndex == index ? '#093476' : '#000', // 高亮颜色
              }"
            >
              <div>
                {{ item.course.courseName }}
              </div>
              <div>
                {{ formatTime(item.course.courseSecond) }}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import {
  computed,
  ref,
  watch,
  onMounted,
  nextTick,
  onBeforeUnmount,
} from "vue";
import { useRouter } from "vue-router";
const router = useRouter();
import { getPlayCoursewareApi } from "@renderer/api/face";
import { openDefenseApi, closeDefenseApi } from "@renderer/api/face";
import { status, data, send, open } from "@renderer/utils/websocket";
import type { User } from "./bean/user";
import type { ComponentSize } from "element-plus";
const size = ref<ComponentSize>("default");
const courseUrl = ref("");
const planId = ref(null);
//当前播放的课件索引
const playIndex = ref(0);
const playState = ref(false);
//培训结束
const trainState = ref(true);
const planInfo = ref({});
const scrollContainer = ref(null);
import MessageType from "@renderer/utils/message";
//已签到人员列表
const userList = ref<User[]>([]);
//记录签到人员工种
const jobTypeList = ref([]);
//签到状态
const signState = ref(false);
const signButtonText = ref("开始签到"); // 新增状态变量
import { ElMessage, ElMessageBox } from "element-plus";
import { useStoreTemplate } from "@renderer/store/modules/template";

const store = useStoreTemplate();

//监听store的值变化
watch(store, (newVal) => {
  if (newVal.messages.serviceType === MessageType.FACE_MESSAGE) {
    trainState.value = true;
    const data = newVal.messages.data;
    //把data对象添加到userList中，如果data.userName已经存在，则不添加
    if (
      !userList.value.some((item) => {
        return item.userName === data.userName;
      })
    ) {
      // 如果用户不存在，添加到列表中
      data.isWatching = true;
      data.watchTime = planInfo.value.totalSecond;
      userList.value.push(data);
    }
    //记录签到人员工种
    if (!jobTypeList.value.includes(data.jobTypeName)) {
      jobTypeList.value.push(data.jobTypeName);
    }
  }
});

watch(playIndex, (newIndex) => {
  nextTick(() => {
    const container = scrollContainer.value;
    const item = container.children[newIndex];
    console.log("item", item);
    if (item) {
      container.scrollLeft += 220; // 向右滚动200px
    }
  });
});

function sign() {
  // 切换按钮文本
  if (signButtonText.value === "开始签到") {
    signState.value = true;
    signButtonText.value = "签到完成"; // 更新为“签到完成”
  } else {
    signState.value = false;
    signButtonText.value = "开始签到"; // 更新为“开始签到”
  }
  const message = {
    serviceType: MessageType.TRAIN_STATE,
    content: JSON.stringify({ trainState: signState.value }),
  };
  send(JSON.stringify(message));
}
// 播放完成事件处理函数
const handleVideoEnded = () => {
  console.log("视频播放完成"); // 在控制台输出信息
  // 判断是否是最后一个视频
  if (playIndex.value < planInfo.value.planCourses.length - 1) {
    // 如果不是最后一个视频，播放下一个视频
    playIndex.value++;
    courseUrl.value =
      planInfo.value.planCourses[playIndex.value].course.courseUrl;
  } else {
    //userlist中所有人的userId用逗号拼接
    // const userIds = userList.value.map((item) => item.userId).join(",");
    const planId = planInfo.value.planId;
    const userTimes = userList.value.map((item) => ({
      userId: item.userId,
      watchTime: item.watchTime,
    }));
    //推送结束消息
    const message = {
      serviceType: MessageType.TRAIN_END,
      content: JSON.stringify({ userTimes, planId }),
    };

    send(JSON.stringify(message));
    ElMessageBox.alert("记录学时成功", "记录结果", {
      // if you want to disable its autofocus
      // autofocus: false,
      confirmButtonText: "确定",
      callback: (_: Action) => {
        router.push("/");
      },
    });
  }
};

// 转换秒数为时分秒格式
const formatTime = (totalSeconds: number) => {
  const hours = Math.floor(totalSeconds / 3600);
  const minutes = Math.floor((totalSeconds % 3600) / 60);
  const seconds = totalSeconds % 60;
  return `${hours}小时 ${minutes}分钟 ${seconds}秒`;
};
// 在组件挂载时启动倒计时
onMounted(() => {
  const planId = router.currentRoute.value.query.planId;
  //获取方案详情
  getPlayCoursewareApi({ planId }).then((res) => {
    if (res.code === 2000) {
      //开始播放
      playState.value = true;
      //获取到待播放课件
      planInfo.value = res.data;
      //设置播放的课件,默认播放第一个
      courseUrl.value = planInfo.value.planCourses[0].course.courseUrl;
      //开始抓拍
      openDefenseApi();
    }
  });
});

//组件销毁时停止倒计时
onBeforeUnmount(() => {
  closeDefenseApi();
});
</script>

<style scoped lang="scss">
@import "./css/study.scss";
</style>
